#include "stdafx.h"
#include <CppUnitTest.h>

#include "nef.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace nef;

__declspec(selectany) char THE_MEANING_OF_LIFE[] = "Stuff";


namespace nef_unit_test
{
	TEST_CLASS(add_export_tests)
	{
	public:
		
		TEST_METHOD(Add_Simple)
		{
			auto cat = Catalog::Create();

			cat->AddPart(shared::Scope(new int(42)));

			auto val = cat->GetExportedValue<int>(NO_CONTRACT, false);

			Assert::IsNotNull(val.get(), L"The exported value was not found.", LINE_INFO());

			Assert::AreEqual(42, *val, L"The exported value was not valid.", LINE_INFO());
		}

		TEST_METHOD(Add_Contracted)
		{
			auto cat = Catalog::Create();
			cat->AddPart(shared::Scope(new int(42)), THE_MEANING_OF_LIFE);
			cat->AddPart(shared::Scope(new int(100)));

			auto fortyTwo = cat->GetExportedValue<int>(THE_MEANING_OF_LIFE, false);
			auto hundred = cat->GetExportedValue<int>(NO_CONTRACT, false);

			Assert::IsNotNull(fortyTwo.get(), L"The exported value was not found. Contract: THE_MEANING_OF_LIFE.", LINE_INFO());
			Assert::IsNotNull(hundred.get(), L"The exported value was not found. Contract: NO_CONTRACT.", LINE_INFO());

			Assert::AreNotEqual(*fortyTwo, *hundred, L"The exported value was incorrect.", LINE_INFO());
		}

		TEST_METHOD(Add_SameContractDiffTypes)
		{
			auto cat = Catalog::Create();
			cat->AddPart(shared::Scope(new int(42)), THE_MEANING_OF_LIFE);
			cat->AddPart(shared::Scope(new double(42)), THE_MEANING_OF_LIFE);

			auto d42 = cat->GetExportedValue<double>(THE_MEANING_OF_LIFE, false);
			auto i42 = cat->GetExportedValue<int>(THE_MEANING_OF_LIFE, false);

			Assert::IsNotNull(d42.get(), L"The exported value for double was not found.", LINE_INFO());
			Assert::IsNotNull(i42.get(), L"The exported value for int was not found.", LINE_INFO());

			Assert::AreEqual(*d42, 42.0, L"The exported double value was not correct.", LINE_INFO());
			Assert::AreEqual(*i42, 42, L"The exported int value was not correct.", LINE_INFO());
		}

		TEST_METHOD(Add_Multiples)
		{
			auto cat = Catalog::Create();

			for (size_t i = 0; i < 5; ++i)
				cat->AddPart(shared::Scope(new size_t(i)), THE_MEANING_OF_LIFE);

			std::vector<std::shared_ptr<size_t>> ct;
			cat->GetExportedValues<size_t>(ct, THE_MEANING_OF_LIFE);

			Assert::AreEqual((int)ct.size(), 5, L"The number of exported values was not correct.", LINE_INFO());
		}
	};
}